package cn.base.web.support.interceptor;

import cn.base.web.authc.AccessStrategy;
import cn.base.web.support.log.WebLog;
import cn.rengy.auth.entity.ResponseEntity;
import cn.rengy.lang.DataConverter;
import cn.rengy.lang.ResultEntity;
import cn.rengy.tool.core.util._DateUtils;
import cn.rengy.util.ExceptionPrintUtils;
import cn.rengy.util.servlet.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * 访问控制拦截器
 */
@Slf4j
@Component
public class AccessControlInterceptor implements HandlerInterceptor {

	@Autowired
	private DataConverter dataConverter;
    @Autowired(required = false)
    private AccessStrategy accessStrategy;
	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		long startTime = System.nanoTime();
		ResultEntity<HttpStatus, ?> resultEntity=accessStrategy.isAccessAllowed(request,response);//是否允许访问
		//
		if(Boolean.FALSE.equals(resultEntity.isSuccess())) {

			//拦截器拦截后无法执行WebLogAspect
			String body=dataConverter.beanToJson(ResultEntity.fail(resultEntity.getMessage()));
			log(request, body, startTime);
			response.setStatus(resultEntity.getCode().value());
			ServletUtil.responseJson(body, response);
		}
        return resultEntity.isSuccess();//允许访问
    }

	private void log(HttpServletRequest request,String result,long startTime){
		String spendTime= _DateUtils.spendFormat(System.nanoTime() - startTime);
		WebLog webLog = new WebLog();
		webLog.setClientip(ServletUtil.getClientIp(request));
		webLog.setMethod(request.getMethod());
		webLog.setMethodParameter(null);
		webLog.setResult(result);
		webLog.setSpendTime(spendTime);
		webLog.setStartTime(startTime);
		webLog.setUrl(ServletUtil.getRequestURL(request));
		webLog.setHeader(ServletUtil.getAllHeader(request));
		webLog.setPayload(ServletUtil.getRequestBody(request));
		webLog.setParameter(ServletUtil.getParameter(request));
		try {
			log.info(dataConverter.beanToJson(webLog));
		} catch (Exception e) {
			log.error(ExceptionPrintUtils.getTrace(e));
		}
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

	}
}
